﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
//地盘
//宫 固定

//人盘 八门
//天盘 = 九神 + 地盘 天干，甲子
//ZYOdatetime -》 局数
//布局 = 甲子戊 起宫数 = 局数
//演局 = 定旬首 取符-星  使-门
//直符 位置 = 旬首

//转天盘 直符= 时辰 的天干
//转人盘八门 直使= 宫数 of 时辰-旬首 加 旬首宫数 mod 9  
//神盘 直符 = 天盘直符

namespace ZYO.基本概念
{

        //public enum 方位 // 九宫格
        //{
        //    东南, 南, 西南,
        //    东, 中, 西,
        //    东北, 北, 西北
        //}    

        public enum e三奇六仪
        {
            戊=0, 己, 庚, 辛, 壬, 癸, 丁, 丙, 乙
        }

        public enum e六旬
        {
            甲子, 甲戌, 甲申, 甲午, 甲辰, 甲寅
        }

        //盘上的位置	1	2	3	4	5	6	7	8


 

        public enum e九宫数
        {
            坎 = 1, 坤, 震, 巽, 中, 乾, 兑, 艮, 离
        }

        public enum e地盘位置
        {
            坎 = 1, 艮, 震, 巽, 离, 坤, 兑, 乾
        }

        //一蓬二芮三冲四辅五禽六心七柱八任九英
        public enum e九神
        {
            天蓬 =1, 天芮, 天冲, 天辅, 天禽, 天心, 天柱, 天任, 天英
        }

    // by 位置
        public enum e八门
        {
            休门 = 1, 生门, 伤门, 杜门, 景门, 死门, 惊门, 开门
            //by 宫数 休门,死门,伤门,杜门 ,开门,惊门,生门,景门

        }

        public enum e八神阳遁
        {
            值符 = 1, 腾蛇, 太阴, 六合, 勾陈, 朱雀, 九地, 九天
        }

        public enum e八神阴遁
        {
            值符 = 1, 九天, 九地, 朱雀, 勾陈, 六合, 太阴, 腾蛇
        }



    public class Class奇门遁甲:ZYObject
    {
        private ZYDateTime pZYODateTime;
        //private Class地盘 pGroundDisk;
        //private Class天盘 pSkyDisk;

        private int iJu;

        private int[] array位置 = { 1, 6, 3, 4, 6, 8, 7, 2, 5 };

        public DataTable dt奇盘;

        public int 值符之宫;
        public e九神 p值符;
        public e八门  p值使;
        public class天干 时干;
        public class地支 时支;

        public class甲子 xunshou;

        public Class奇门遁甲(DateTime dt)
        {

            pZYODateTime = new ZYDateTime(dt);
            iJu = pZYODateTime.所处之局;
            xunshou = pZYODateTime.时干支.旬首;
            时干 = pZYODateTime.时干支.天干;
            时支 = pZYODateTime.时干支.地支;

            dt奇盘 = new DataTable("奇盘");
           
            dt奇盘.Columns.Add(资源.FieldName.九宫数, typeof(int));
            dt奇盘.Columns.Add(资源.FieldName.位置, typeof(int));
            dt奇盘.Columns.Add(资源.FieldName.八卦, typeof(String));
            dt奇盘.Columns.Add(资源.FieldName.地盘宫五行, typeof(String));
            dt奇盘.Columns.Add(资源.FieldName.地盘三奇六仪, typeof(String));
            dt奇盘.Columns.Add(资源.FieldName.地盘六旬, typeof(String));
            dt奇盘.Columns.Add(资源.FieldName.天盘九星, typeof(String));
            dt奇盘.Columns.Add(资源.FieldName.原天盘九星, typeof(String));
            dt奇盘.Columns.Add(资源.FieldName.天盘三奇六仪, typeof(String));
            dt奇盘.Columns.Add(资源.FieldName.八门, typeof(String));
            dt奇盘.Columns.Add(资源.FieldName.原八门, typeof(String));
            dt奇盘.Columns.Add(资源.FieldName.八神, typeof(String));
            dt奇盘.Columns.Add(资源.FieldName.is值符, typeof(Boolean));
            dt奇盘.Columns.Add(资源.FieldName.原is值符, typeof(Boolean));

            dt奇盘.DefaultView.Sort = 资源.FieldName.位置;
            // Add rows by 宫数
            for (int i = 1; i <= 9; i++)
            {
                DataRow row = dt奇盘.NewRow();
                row[资源.FieldName.九宫数] = i;
                row[资源.FieldName.位置] = array位置[i - 1];

                row[资源.FieldName.八卦] = ((e九宫数)i).ToString();

                if (5 == i)//中宫
                {
                    row[资源.FieldName.地盘宫五行] = "土";
                }
                else
                {
                    class八卦 bagua = new class八卦(row[资源.FieldName.八卦].ToString());
                    row[资源.FieldName.地盘宫五行] = bagua.五行属性.ToString();
                }


                row[资源.FieldName.原天盘九星] = ((e九神)i).ToString();


                //开始布局
                // 三奇六仪 is 0 based

                int qiyi;
                if (iJu > 0)//阳 局
                {
                    qiyi = (9 + i - iJu) % 9;
                }
                else //阴局
                {
                    qiyi = (9 - i - iJu) % 9;
                }

                row[资源.FieldName.地盘三奇六仪] =  ((e三奇六仪)qiyi).ToString();

                if (qiyi < 6) // 六仪 对应 六旬
                {
                    row[资源.FieldName.地盘六旬] = ((e六旬)qiyi).ToString();
                }

                //定值符， 值使 之宫

                row[资源.FieldName.原is值符] = (xunshou.Name == row[资源.FieldName.地盘六旬].ToString());

                if (true == (bool)row[资源.FieldName.原is值符])
                {
                    this.p值符 = (e九神)i;
                }

                dt奇盘.Rows.Add(row);
            }

           
            // 位置 旋转
            int 值符之宫数 = (int)this.p值符;
            int 时支落宫;

            if (iJu > 0)
            {
                时支落宫 = mod((值符之宫数 + (pZYODateTime.时干支 - pZYODateTime.时干支.旬首)), 9);
            }
            else //阴局倒数
            {
                时支落宫 = mod((值符之宫数 - (pZYODateTime.时干支 - pZYODateTime.时干支.旬首)), 9);
            }
            if (时支落宫 <= 0)
            {
                时支落宫 = 时支落宫 + 9;
            }

            //array位置 based on 0
            int 人盘偏移量 = array位置[时支落宫 - 1] - array位置[值符之宫数 - 1];

            //天盘九星
            // 转天盘，偏移量

            int 天盘偏移量 = 0;
            int 神盘偏移量 = 0;
            if ("甲" != 时干.Name) //六甲之时,伏吟,偏移量为0
            {
                DataRow row地盘时干 = dt奇盘.Select(String.Format("地盘三奇六仪='{0}'", 时干.Name))[0];
                //DataRow row值符 = dt奇盘.Select("原is值符=true")[0];
                天盘偏移量 = (int)row地盘时干[资源.FieldName.位置] - array位置[值符之宫数 - 1];
                神盘偏移量 = (int)row地盘时干[资源.FieldName.位置] - array位置[0];
            }


            for (int k = 1; k <= 9; k++)
            {
                DataRow row九宫数 = dt奇盘.Select(String.Format("九宫数='{0}'", k))[0];

                int 当前位置 = (int)row九宫数[资源.FieldName.位置];

                DataRow[] rows原天盘九星 = dt奇盘.Select(String.Format("位置='{0}'", OriginalPosition(当前位置, 天盘偏移量)));

                foreach (DataRow row in rows原天盘九星)
                {
                    row九宫数[资源.FieldName.is值符] = (bool)row[资源.FieldName.原is值符];
                    row九宫数[资源.FieldName.天盘九星] += row[资源.FieldName.原天盘九星].ToString();
                    row九宫数[资源.FieldName.天盘三奇六仪] += row[资源.FieldName.地盘三奇六仪].ToString();
                }
            } // k


            // 遍历8个位置 
            for (int j = 1; j <= 8; j++)
            {
                DataRow[] rows = dt奇盘.Select(String.Format("位置='{0}'",j));

                if (null != rows && rows.GetLength(0) > 0)
                {
                    foreach (DataRow row in rows)
                    {
                        int new八神 = mod( ((j - 神盘偏移量) + 8) , 8);
 
                        if (iJu > 0)
                        {
                            //转 神盘 八神
                            row[资源.FieldName.八神] = ((e八神阳遁)new八神).ToString();
                        }
                        else
                        {
                            //转 神盘 八神
                            row[资源.FieldName.八神] = ((e八神阴遁)new八神).ToString();
                        }

                        row[资源.FieldName.原八门] = ((e八门)j).ToString();

                        if ((bool)row[资源.FieldName.原is值符])
                        {
                            this.p值使 = (e八门)j;
                        }

                        // 转人盘，八门
                        int newPosition = mod((8 + j - 人盘偏移量), 8);
                        if (0 == newPosition)
                        {
                            newPosition = 8;
                        }

                        row[资源.FieldName.八门] = (e八门)newPosition;

                        

                    }
                }

            }//For
        } // Function

        /// <summary>
        /// 旋转前的位置
        /// </summary>
        /// <param name="当前位置"></param>
        /// <returns>返回旋转前的位置</returns>
        private int OriginalPosition(int 当前位置, int 旋转偏移量)
        {
            int position = mod((8 + 当前位置 - 旋转偏移量), 8); //转盘上有8个方位
            return position;
        } 

    } // Class

}
